package graph_viewer.structure;

import java.util.*;

import graph_viewer.drawer.*;
import graph_viewer.layout.*;
import graph_viewer.util.*;

/**
 * define tree node. Every node is a cluster and whether it is drawn is denpent on the variable: is_closed.
 * 
 */
public class Node implements Visual_Component{
	private	ArrayList			children;
	private	Node			parent;		
	private	Node_Position	position;
	private	String			label, brief_text, text;
	private	String			type;
	private	int				DOI;
	
	private	boolean			is_closed;	// a node is closed, then its children wont display. A closed node is presented as a leaf of a cluster tree, and a graph vertex.
	private	boolean			is_psuedo;	// after do cluster operations such as close/open a cluster, a new psuedo node might be created
	
	//@since 5/07/2004 for animation
	private	boolean			is_labelled;	// default is true.

	//============================================================================
	// construtors
	//============================================================================
	public Node(){
		children        	= new ArrayList();		
		
		set_is_closed( true );
		set_is_psuedo( false );
		set_is_labelled( true );

		set_text( "_no _details" );

		set_DOI( Structure_Util.get_default_doi() );
	 }
        
	public Node(String a_label){
		this();
		set_label( a_label );
		set_text( a_label + "_brief _details" );
	 }
        
	public Node( String a_label, Node_Position a_np ){
		this( a_label );
		set_position( new Node_Position( a_np ) );
	}

	public Node(String a_label, Node parent){
		this( a_label );
		set_parent( parent);
	}

	public Node(String a_label, Node parent, Node_Position a_np, boolean is_closed, int DOI ){
		this( a_label, parent, is_closed );
		set_position( new Node_Position( a_np ) );
		set_DOI( DOI );
	}

	public Node(String a_label, Node parent, boolean is_closed){
		this( a_label, parent );
		set_is_closed( is_closed );
	}

	public Node( Node a_node ){
		this( a_node.get_label(), a_node.get_parent(), a_node.get_position(), a_node.get_is_closed(), a_node.get_DOI() );
		set_is_psuedo( a_node.get_is_psuedo() );
		set_brief_text( a_node.get_brief_text() );
		set_text( a_node.get_text() );
	}
	
	//============================================================================
	// public methods
	//============================================================================
	public boolean has_label( String a_node_label  ){
		return  get_label().equals (a_node_label);
	}

	public void add_child( Node a_child ){
		children.add( a_child );
	}
	
	public void delete_child( Node a_child ){
		if ( children.contains( a_child ) ){
			children.remove( a_child );
		}
	}
	
	public boolean is_leaf(){
		return get_children().size() == 0;	
	}

	public boolean is_leaf_cluster(){
		if ( is_root() ){
			return false;
		}

		Node parent	= get_parent();

		boolean 
			is_parent_closed	= parent.get_is_closed(),
			is_self_closed		= get_is_closed();

		Debug.println( this + ": is_parent_closed " + is_parent_closed + ", is_self_closed" + is_self_closed, 22 );
		
		boolean is_leaf_cluster	= is_self_closed && (!is_parent_closed);
		
		Debug.println( "\tis_leaf_cluster: " + is_leaf_cluster, 22 );
		return is_leaf_cluster;
	}
	
	public boolean is_super_clusters(){
		return ! (is_leaf() || is_leaf_cluster() || is_root() );	
	}

	public boolean is_root(){
		return get_parent() == null;
	}
	
	public boolean is_sibling( Node a_node ){
		if ( is_root() || a_node.is_root() ){
			return false;
		}
		
		return get_parent() ==  a_node.get_parent();		
	}

	public boolean is_irrelevant (){
		return get_DOI() == Graph.MIN_DOI;
	}

	public boolean is_magnified(){
		Node_Position distorted_position	= this.get_position();
		int	 
			width	 = distorted_position.get_width(),
			height = distorted_position.get_height();
		
		return ( width > Structure_Util.find_default_node_width() && height > Structure_Util.find_default_node_height() );		
	
	}

	public boolean is_displayed( ){
		boolean
			is_closed			= get_is_closed(),
			is_leaf_cluster		= is_leaf_cluster();

		return (!is_closed) || is_leaf_cluster;
	}
	
	// has the same label
	public boolean is_copy( Node another_node ){
		String 
			node_label	= get_label(),
			another_label	= another_node.get_label();

		return node_label.equals( another_label );
	}

	public boolean is_overlapped( Node another_node ){
		if ( !another_node.is_displayed() ){
			return  false;
		}

		Node_Position 
			the_node_position		= get_position(),
			another_node_position	= another_node.get_position();

		return the_node_position.is_overlapped( another_node_position );
	}
	
	
	//@deprecated. 
	public boolean is_logic_filtered( int k ){
		return ( get_DOI() < k );		
	}
	
	public ArrayList find_children_labels(){
		ArrayList children_labels	 = new ArrayList();

		for ( Iterator _i = children.iterator(); _i.hasNext(); ){
			Node a_child	= (Node)_i.next();

			children_labels.add( a_child.get_label() );
		}

		return children_labels;
	}
	
	public String toString(){
		String string	= //get_label();
						Drawer_Util.get_displayed_label( this );//get_label();
		String app	= "";//
		
		/*if ( is_root() ){
			app = " IS ROOT";
		}else{
			app = get_parent().get_label();
		}*/
		
		//app += ", Is closed? " + get_is_closed();
		//app +=  "" + get_position() + "\n" ;//+ get_text();// + ", closed: " + get_is_closed();
			//"";//", Is leaf_cluster? " + is_leaf_cluster();
				//get_position();
	
		return string + app;
	}
	
	//============================================================================
	// setter and getter
	//============================================================================
	//adapter setter&getter
	public void set_width( int width ){
		get_position().set_width( width );
	}

	public int get_width(){
		return get_position().get_width();
	}

	public void set_height( int height ){
		get_position().set_height( height );
	}

	public int get_height(){
		return get_position().get_height();
	}
	
	//self 
	public void set_children( ArrayList children ){
		this.children.clear();
		this.children	= new ArrayList( children );
	}
	
	public ArrayList get_children(){
		return this.children;
	}

	public void set_parent( Node parent ){
		this.parent	= parent;
	}
	
	public Node get_parent(){
		return this.parent; 
	}
	
	public void set_label( String label ){
		this.label	= label;
	}

	public String get_label(){
		return this.label;
	}

	public void set_brief_text( String brief_text ){
		this.brief_text	= brief_text;
	}

	public String get_brief_text(){
		return this.brief_text;
	}
	
	public void set_text( String text ){
		this.text = text;
	}
	public String get_text(){
		return this.text;
	}

	public void set_type( String type ){
		this.type	 = type;
	}

	public String get_type(){
		return this.type;
	}
	
	public void set_DOI( int doi ){
		this.DOI	= doi;
	}

	public int get_DOI( ){
		return this.DOI;
	}

	public void set_position ( Node_Position n_p ){
		this.position	= n_p;
	}

	public Node_Position get_position(){
		return this.position;
	}

	public void set_is_closed( boolean status ){
		this.is_closed	= status;
	}

	public boolean get_is_closed(){
		return this.is_closed;
	}

	public void set_is_psuedo( boolean status ){
		this.is_psuedo	= status;
	}

	public boolean get_is_psuedo(){
		return this.is_psuedo;
	}	

	public void set_is_labelled( boolean status ){
		this.is_labelled	 = status;
	}

	public boolean get_is_labelled(){
		return this.is_labelled;
	}
}